package com.ap.core.jbehave;

import com.ap.core.cxf.jaxb.acknowledgement.MessageStatusEnum;
import com.ap.core.cxf.jaxb.common.DeliveryType;
import com.ap.core.cxf.jaxb.common.ResponseCode;
import com.ap.core.cxf.jaxb.common.ResponseWithIntentType;
import com.ap.core.cxf.jaxb.managepayment.*;
import com.ap.core.cxf.jaxb.managertp.SubmitRTP1Request;
import com.ap.core.cxf.jaxb.managertp.SubmitRTP1Response;
import com.ap.core.cxf.jaxb.managertp.SubmitRTPMessageType;
import com.ap.core.cxf.jaxb.msghdr.MessageType;
import com.ap.core.cxf.jaxb.msghdr.MsgHdrType;
import com.ap.core.cxf.jaxb.paymentdetails.TxnStatusDescType;
import com.ap.core.cxf.jaxb.paymentdetails.TxnStatusType;
import com.ap.core.cxf.jaxb.rtp.RTPSenderInfoType;
import com.ap.core.cxf.jaxb.rtp.TransactionCheckOutType;
import com.ap.core.util.Nullable;
import com.ap.generator.confirmpayment.ConfirmPaymentRequestGeneratorBuilder;
import com.ap.generator.retrievertp.RetrieveRTPRequestTypeGeneratorBuilder;
import com.ap.generator.submitrtp.SubmitRTPTypeInfoGeneratorBuilder;
import org.hamcrest.CoreMatchers;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

/**
 * User: Ranjit.Singh
 */
public class BaseTransitionRTPSteps extends  BaseRTPSteps{


    protected BaseTransitionRTPSteps(StoryContext storyContext) {
        super(storyContext);
    }

    protected SubmitRTP1Request createSubmitRTPRequest(SubmitRTPMessageType messageType) {
        return SubmitRTPTypeInfoGeneratorBuilder.getSubmitRTPTypeGenerator().getSubmitRTPType(messageType).build().generate();
    }

    protected RetrieveRTP1Request createRetrieveRTPRequest() {
        return RetrieveRTPRequestTypeGeneratorBuilder.getRetrieveRTPTypeGenerator().build().generate();
    }

    protected ConfirmPayment1Request createConfirmPayment1Request(MessageType messageType, TransactionCheckOutType transactionCheckOutType, DeliveryType deliveryType) {
        ConfirmPayment1Request confirmPayment1Request = ConfirmPaymentRequestGeneratorBuilder.getConfirmPaymentRequestGenerator().build().generate();
        /*if(TransactionCheckOutType.NRMLCHK == transactionCheckOutType){
            confirmPayment1Request.getPaymtDetails().setQkPayDelAddress(null);
        }*/
        if(TransactionCheckOutType.NRMLCHK == transactionCheckOutType || (TransactionCheckOutType.QKPACHK == transactionCheckOutType && DeliveryType.DELTAD != deliveryType)){
        	confirmPayment1Request.getPaymtDetails().setQkPayDelAddress(null);
        }
        return confirmPayment1Request;
    }


    protected void doSubmitRTPResponseAssertions(Nullable<SubmitRTP1Response> responseRTPType, SubmitRTP1Request submitRTP1Request) {

        assertThat("Didn't receive ResponseWithIntentType", false, CoreMatchers.is(equalTo(responseRTPType.hasNull())));

        final MsgHdrType msgHdrType = responseRTPType.value().getMsgHdr();

        assertThat("MsgType is not as expected", true, CoreMatchers.is(equalTo(msgHdrType.getMsgType() == MessageType.RESPONSETORTP)));
        assertThat("OrgReqMsgId is not as expected", true, CoreMatchers.is(equalTo(msgHdrType.getOrgReqMsgId().equals(submitRTP1Request.getMsgHdr().getMsgId()))));
        assertThat("MsgTimestamp is not as expected", false, CoreMatchers.is(equalTo(msgHdrType.getMsgTimestamp() == null)));

        final ResponseWithIntentType responseWithIntentType = responseRTPType.value().getResponseInfo();
        assertThat("ResponseStatus is not as expected", true, CoreMatchers.is(equalTo(responseWithIntentType.getResponseStatus().getResponseCode() == ResponseCode.SUCCESSFUL)));
        assertThat("RTPId is not as expected", true, CoreMatchers.is(equalTo(responseWithIntentType.getRTPId().equals(submitRTP1Request.getRTPSummary().getTxIdentification().getRTPId()))));
        assertThat("APTransactionId is not as expected", false, CoreMatchers.is(equalTo(responseWithIntentType.getApTransactionId() == null)));
        assertThat("APTransactionRetrievalId is not as expected", false, CoreMatchers.is(equalTo(responseWithIntentType.getApTRId() == null)));
        assertThat("ReconId is not as expected", false, CoreMatchers.is(equalTo(responseWithIntentType.getReconId() == null)));
    }

    protected void doRetrieveRTPResponseAssertions(Nullable<RTPSummaryType> rtpSummaryType, Nullable<RTPSenderInfoType> rtpSenderInfoType, Nullable<String> retrieveRTPMsgType) {
        LOG.info("Then -  the RTPFORAUTH message is sent to the OSB");
        assertThat("Retrieve RTP message type is not null", false, CoreMatchers.is(CoreMatchers.equalTo(retrieveRTPMsgType.equals("RTPFORAUTH"))));
        assertThat("RTPSummary Details are not null", false, CoreMatchers.is(CoreMatchers.equalTo(rtpSummaryType.hasNull())));
        assertThat("RTPSender Info is not null", false, CoreMatchers.is(CoreMatchers.equalTo(rtpSenderInfoType.hasNull())));

        LOG.info("Test executed successfully...");
    }

    protected void doConfirmPaymentResponseAssertions(Nullable<ConfirmPayment1Response> confirmPayResponse, ConfirmPayment1Request confirmPayment1Request, SubmitRTP1Request submitRTP1Request) {
        assertThat("Didn't receive response", false,
                CoreMatchers.is(equalTo(confirmPayResponse.hasNull())));

        final MsgHdrType msgHdrType = confirmPayResponse.value().getMsgHdr();
        
        PaymentStatusType paymentStatus = confirmPayResponse.value().getPaymentStatus();
        

        assertThat("MsgType is not as expected", true, CoreMatchers.is(equalTo(msgHdrType.getMsgType() == MessageType.RSPTOPAYMENTCONFIRMATION)));
        assertThat("OrgReqMsgId is not as expected", true, CoreMatchers.is(equalTo(msgHdrType.getOrgReqMsgId().equals(confirmPayment1Request.getMsgHdr().getMsgId()))));
        assertThat("MsgTimestamp is not as expected", false, CoreMatchers.is(equalTo(msgHdrType.getMsgTimestamp() == null)));

        final Nullable<NotifyRecipientInfoType> notifyRecipientInfo = Nullable.nullable(confirmPayResponse.value().getNotifyRecipientInfo());
        assertThat("NotifyRecipientInfo is null", false, CoreMatchers.is(equalTo(notifyRecipientInfo.hasNull())));
        assertThat("RTPId is not matching with the original RTPId", true, CoreMatchers.is(equalTo(notifyRecipientInfo.value().getRTPId().equals(submitRTP1Request.getRTPSummary().getTxIdentification().getRTPId()))));
        assertThat("Merchant Id is not matching with the original MerchantId", true, CoreMatchers.is(equalTo(notifyRecipientInfo.value().getMerchantId().equals(submitRTP1Request.getRTPSenderInfo().getDetailMerchantInfo().getMerchantInfo().getMerchantId()))));
        assertThat("DistributorId is not matching with the original DistributorId", true, CoreMatchers.is(equalTo(notifyRecipientInfo.value().getDistributorId().equals(submitRTP1Request.getRTPSenderInfo().getDistributorInfo().getDistributorId()))));

        final Nullable<EndpointsType> endpoints = Nullable.nullable(confirmPayResponse.value().getEndpoints());

        assertThat("EndpointsType is null", false, CoreMatchers.is(equalTo(endpoints.hasNull())));
        assertThat("endpoint is empty", false, CoreMatchers.is(equalTo(endpoints.value().getEndpoint().isEmpty())));

        final Nullable<EndpointType> endpoint = Nullable.nullable(endpoints.value().getEndpoint().get(0));
        assertThat("SiteName is null", false, CoreMatchers.is(equalTo(endpoint.value().getSiteName() == null)));
        assertThat("TargetURI is null", false, CoreMatchers.is(equalTo(endpoint.value().getTargetURI() == null)));

        final Nullable<AckStatusType> ackType = Nullable.nullable(confirmPayResponse.value().getAckStatus());
        assertThat("ackType is null", false, CoreMatchers.is(equalTo(ackType.hasNull())));
        assertThat("MessageStatus is not RECD", true, CoreMatchers.is(equalTo(ackType.value().getMessageStatus() == MessageStatusEnum.RECD)));
        
        if(confirmPayment1Request.getPaymtDetails().getPaymentStatusInfo().getTxnStatus() == TxnStatusType.DECLINED ){
        	assertThat("TxnStatus is DECLINED", true, CoreMatchers.is(equalTo(paymentStatus.getTxnStatus() == TxnStatusType.DECLINED)));
        	assertThat("TxnStatusDesc is DEclined", true, CoreMatchers.is(equalTo(paymentStatus.getTxnStatusDesc()== TxnStatusDescType.DECLINED)));
         }
        
    }

}
